📘 Khy-OS 文档站 🧭 新手先读:核心概念

管理前端自动可用修复

<!-- 文档分类: IMPL-RPT-018 | 阶段: 实现 | 原路径: docs/指南/管理前端自动可用修复-2026-05-31.md -->

管理前端自动可用修复#

日期: 2026-05-31 | 影响: khy gateway manage

问题#

khy gateway manage 启动管理界面时,前端始终显示 "未就绪(pip 安装暂不含预构建前端)",
即使 ai-frontend/dist/ 已有完整构建产物。

前端: 未就绪
前端原因: unavailable
推荐入口: API 直管(当前无可用前端)

根因分析#

三处断裂导致前端不可用:

断裂 1: setup.py 不打包 ai-frontend/#

BuildWithBundle.run() 只复制 frontend/dist/(旧路径,已不存在),
从未打包 ai-frontend/ 源码或预构建产物。pip 安装后目标机器上没有前端文件。

断裂 2: _bootstrap.py 不装 ai-frontend 依赖#

runtime npm install 只针对 backend/,从未对 ai-frontend/ 执行。
即使前端源码存在,缺少 node_modules 导致 Vite dev server 无法启动。

断裂 3: daemon 不回退到静态 dist#

ai-manage-daemon.js 存在以下问题:

  • 不解析 --frontend-dist-dir 参数(spawner 传了但 daemon 忽略了)
  • 不调用 aiManagementServer.configureFrontendStatic()(函数已导出但从未被使用)

当 node_modules 缺失时,noAutoFrontend 自动设为 true,
resolveFrontend() 跳过 Vite dev server,外部端口探测也失败,结果 frontendAvailable = false。

修复#

1. setup.py — 打包 ai-frontend/#

在 BuildWithBundle.run() 中添加 ai-frontend/ copytree:

ai_frontend_src = ROOT / "ai-frontend"
ai_frontend_dst = bundled / "ai-frontend"
if ai_frontend_src.exists():
    shutil.copytree(
        ai_frontend_src, ai_frontend_dst,
        ignore=shutil.ignore_patterns(*EXCLUDE_PATTERNS, 'node_modules'),
    )

MANIFEST.in 同步添加 recursive-include ai-frontend * + prune ai-frontend/node_modules。

2. _bootstrap.py — ai-frontend npm install#

在 _ensure_npm_install() 的 finally 块中添加 ai-frontend 依赖安装:

ai_frontend_dir = backend_dir.parent / "ai-frontend"
if ai_frontend_dir.exists() and (ai_frontend_dir / "package.json").exists():
    nm = ai_frontend_dir / "node_modules"
    lock = nm / ".package-lock.json"
    if not _path_exists_safe(nm) or not _path_exists_safe(lock):
        subprocess.run(
            [npm_cmd, "install", "--no-audit", "--no-fund"],
            cwd=str(ai_frontend_dir), timeout=_NPM_TIMEOUT,
            **_subprocess_kwargs(),
        )

3. ai-manage-daemon.js — 解析参数 + 静态回退#

解析 --frontend-dist-dir 参数:

const frontendDistDir = parseStringArg(argv, '--frontend-dist-dir', '');

resolveFrontend() 失败后回退到静态托管:

if (!frontend.available && frontendDistDir) {
    const staticResult = aiManagementServer.configureFrontendStatic({
        distDir: frontendDistDir,
    });
    if (staticResult.enabled) {
        frontend.available = true;
        frontend.managed = true;
        frontend.port = apiPort;        // 静态文件从 API 端口提供
        frontend.reason = 'static-dist';
    }
}

4. gateway.js — 修正提示信息#

移除硬编码的 "pip 安装暂不含预构建前端" 文案,改为通用 "管理前端未就绪"。

修复后行为#

场景前端来源端口
有 node_modulesVite dev server8090
无 node_modules,有 dist/configureFrontendStatic() 静态托管9090 (API 同端口)
pip 安装首次启动runtime npm install 后 Vite dev server8090

完整链路:

pip install → 打包 ai-frontend/ (源码 + dist/)
→ runtime _bootstrap.py → cd ai-frontend && npm install
→ khy gateway manage → daemon → 优先 Vite dev server (8090)
                              → 回退 configureFrontendStatic (9090/admin/ai-gateway)
                              → 前端可用

修改文件#

文件改动
setup.pyBuildWithBundle.run() 添加 ai-frontend copytree
MANIFEST.in添加 ai-frontend include + prune node_modules
khy_platform/_bootstrap.py_ensure_npm_install() finally 块安装 ai-frontend 依赖
backend/scripts/ai-manage-daemon.js解析 --frontend-dist-dir + 静态回退
backend/src/cli/handlers/gateway.js修正 "未就绪" 提示信息

验证#

# 正常模式(有 node_modules)
khy gateway manage
# → 前端: http://127.0.0.1:8090

# 模拟 pip 场景(无 node_modules)
mv ai-frontend/node_modules ai-frontend/_bak
khy gateway manage stop && khy gateway manage start --daemon
# → 前端: http://127.0.0.1:9090 (静态 dist 回退)
curl -s http://127.0.0.1:9090/admin/ai-gateway | head -1
# → <!DOCTYPE html>

# 恢复
khy gateway manage stop
mv ai-frontend/_bak ai-frontend/node_modules